<template>
    <ol-map
        :load-tiles-while-animating="true"
        :load-tiles-while-interacting="true"
        :controls="[]"
        class="map_container"
        style="position: relative; width: 100%; height: 100%"
        @singleclick="singleclickHandler"
    >
        <ol-view ref="mapViewRef" :center="[116.692877, 39.54359]" :zoom="8" projection="EPSG:4326" />
        <ol-tile-layer>
            <ol-source-tianditu
                layer-type="vec"
                projection="EPSG:4326"
                tk="dbed7e0f96194affd82763e159de4c50"
                :hidpi="true"
            />
        </ol-tile-layer>
        <ol-vector-layer ref="legendLayerRef">
            <ol-source-vector ref="legendLayerSourceRef">
                <template v-if="featuresVisible">
                    <ol-feature v-if="pointVisible" :properties="featureProperties">
                        <ol-geom-point :coordinates="coordinateTemplate.point"></ol-geom-point>
                    </ol-feature>
                    <ol-feature v-if="polygonVisible" :properties="featureProperties">
                        <ol-geom-polygon :coordinates="coordinateTemplate.polygon"></ol-geom-polygon>
                    </ol-feature>
                    <ol-feature v-if="lineStringVisible" :properties="featureProperties">
                        <ol-geom-line-string :coordinates="coordinateTemplate.lineString"></ol-geom-line-string>
                    </ol-feature>
                </template>
            </ol-source-vector>
        </ol-vector-layer>
    </ol-map>
</template>
<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick, onBeforeUnmount } from 'vue'
import OlStyleParser from 'geostyler-openlayers-parser'
import type { Rule as GeoRule } from 'geostyler-style'
const emit = defineEmits(['singleclick'])
const featureProperties = ref<Record<string, string | number>>({})
// 符号坐标模板
const coordinateTemplate = {
    point: [7.10066, 50.735851],
    polygon: [
        [
            [7.1031761169433585, 50.734268655851345],
            [7.109270095825195, 50.734268655851345],
            [7.109270095825195, 50.73824770380063],
            [7.1031761169433585, 50.73824770380063],
            [7.1031761169433585, 50.734268655851345],
        ],
    ],
    lineString: [
        [7.062578201293945, 50.721786104206004],
        [7.077512741088867, 50.729610159968296],
        [7.082319259643555, 50.732435192351126],
        [7.097940444946289, 50.73748722929948],
        [7.106866836547852, 50.73775882875318],
        [7.117509841918945, 50.73889952925885],
        [7.129182815551758, 50.7504679214779],
    ],
}
type MapSymbolProps = {
    geoRule?: GeoRule
}
// 地图view
const mapViewRef = ref<any>(null)
// 图例图层
const legendLayerRef = ref<any>(null)
const featuresVisible = ref(false)
// 图例图层数据源
const legendLayerSourceRef = ref<any>(null)
const props = withDefaults(defineProps<MapSymbolProps>(), {
    geoRule: () => ({
        name: 'default',
        filter: undefined,
        scaleDenominator: {
            min: undefined,
            max: undefined,
        },
        symbolizers: [
            {
                kind: 'Fill', // 规则类型
                color: '#ff0000',
                fillOpacity: 1,
                outlineColor: '',
                outlineWidth: 0,
                outlineOpacity: 1,
                outlineDasharray: [],
            },
        ],
    }),
})
const layerVisible = computed(() => {
    return props.geoRule.symbolizers.length > 0
})
// 是否显示点类型符号
const pointVisible = computed(() => {
    return ['Mark', 'Text'].includes(props.geoRule.symbolizers[0]!.kind)
})
// 是否显示面类型符号
const polygonVisible = computed(() => {
    return ['Fill'].includes(props.geoRule.symbolizers[0]!.kind)
})
// 是否显示线类型符号
const lineStringVisible = computed(() => {
    return ['Line'].includes(props.geoRule.symbolizers[0]!.kind)
})
const initLegendStyle = () => {
    if (
        layerVisible.value &&
        legendLayerRef.value &&
        legendLayerRef.value.vectorLayer.getSource().getFeatures().length > 0
    ) {
        //缩放到当前要素
        mapViewRef.value?.fit(legendLayerRef.value.vectorLayer.getSource().getExtent())
        const olStyleParser = new OlStyleParser()
        const style = {
            name: 'PreviewSymbolizer',
            rules: [JSON.parse(JSON.stringify(props.geoRule))],
        }
        olStyleParser.writeStyle(style).then(olStyleRes => {
          //不知为何 此处不能从图层上设置样式
          legendLayerRef.value?.vectorLayer.getSource().getFeatures().forEach((singleFeature:any)=>{
            singleFeature.setStyle(olStyleRes.output)
          })
        })
    }
}
/**
 * @description: 地图点击事件
 * @return {*}
 */
const singleclickHandler = () => {
    emit('singleclick')
}
watch(
    () => props.geoRule,
    () => {
        setTimeout(() => {
            initLegendStyle()
        }, 300)
    },
    {
        deep: true,
    },
)
onMounted(() => {
    // 因为openlayers 的Featuren的添加和移除都是异步的 所以此处不能直接执行
    legendLayerSourceRef.value?.source.on('addfeature', () => {
        initLegendStyle()
    })
    if (props.geoRule.filter && props.geoRule.filter instanceof Array && props.geoRule.filter.length > 0) {
        const cqlOperator = props.geoRule.filter[0]
        const cqlProperty = props.geoRule.filter[1] as string
        const cqlValue = props.geoRule.filter[2] as string
        if (cqlOperator == '==') {
            featureProperties.value[cqlProperty] = cqlValue
        }
    }
    featuresVisible.value = true
})
onBeforeUnmount(() => {})
</script>
